﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace CLDataAppManagement
{
    public class DataAppManagement
    {
        /// <summary>
        /// 文件路径
        /// </summary>
        public string jsonPath;
        public DataAppManagement()
        {

        }
        public DataAppManagement(string path)
        {
            this.jsonPath = path;
        }
        /// <summary>
        /// 加载json
        /// </summary>
        /// <returns></returns>
        public JObject LoadJsonFromFile(out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            try
            {
                string jsonText = File.ReadAllText(this.jsonPath, Encoding.UTF8);
                JObject keyValuePairs = JObject.Parse(jsonText);
                return keyValuePairs;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "加载文件失败！" + ex.ToString();
                return null;
            }
        }
        /// <summary>
        /// 从本地加载json文件
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public JObject LoadJsonFromFile(string path, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            this.jsonPath = path;
            try
            {
                string jsonText;
                using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    using (StreamReader streamReader = new StreamReader(fs, Encoding.UTF8))
                    {
                        jsonText = streamReader.ReadToEnd();
                    }
                }
                JObject keyValuePairs = JObject.Parse(jsonText);
                return keyValuePairs;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "保存文件失败！" + ex.ToString();
                return null;
            }
        }
        /// <summary>
        /// 保存json文件到本地
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <param name="filePath"></param>
        public void SaveJsonToFile(JObject jsonObject, string filePath, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            try
            {
                string jsonData = jsonObject.ToString(Newtonsoft.Json.Formatting.Indented);
                //File.WriteAllText(filePath, jsonData);

                using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write))
                {
                    using (StreamWriter streamWriter = new StreamWriter(fs))
                    {
                        streamWriter.Write(jsonData);
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "保存文件失败！" + ex.ToString();
            }

        }


        /// <summary>
        /// 添加新键值
        /// </summary>
        /// <param name="keyName">新的键（a.b.c）</param>
        /// <param name="value">值</param>
        public void AddKeyValue(string keyName, JToken value, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            JObject jsonData = LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                // Split the path to find the parent object
                string[] keys = keyName.Split('.');
                JObject current = jsonData;

                // Navigate to the object that will contain the new key
                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else
                    {
                        // If any segment of the path does not exist, create new JObject containers
                        current[keys[i]] = new JObject();
                        current = (JObject)current[keys[i]];
                    }
                }

                // Add the new key with the provided value
                string newKey = keys[keys.Length - 1];
                if (!current.ContainsKey(newKey))
                {
                    current[newKey] = value;  // Directly add the string value
                    this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
                    if (ErrorCode == -1) { return; }

                }
                else
                {
                    ErrorCode = -1;
                    ErrorText = $"Key '{newKey}' 已经存在";
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "添加失败！" + ex.ToString();
            }
        }
        public void AddKeyValue(string keyName, string value, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            JObject jsonData = LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                // Split the path to find the parent object
                string[] keys = keyName.Split('.');
                JObject current = jsonData;

                // Navigate to the object that will contain the new key
                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else
                    {
                        // If any segment of the path does not exist, create new JObject containers
                        current[keys[i]] = new JObject();
                        current = (JObject)current[keys[i]];
                    }
                }

                // Add the new key with the provided value
                string newKey = keys[keys.Length - 1];
                if (!current.ContainsKey(newKey))
                {
                    current[newKey] = value;  // Directly add the string value
                    this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
                    if (ErrorCode == -1) { return; }

                }
                else
                {
                    ErrorCode = -1;
                    ErrorText = $"Key '{newKey}' 已经存在";
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "添加失败:" + ex.Message;
            }
        }
        public void AddKeyValue(string keyName, int value, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            JObject jsonData = LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                // Split the path to find the parent object
                string[] keys = keyName.Split('.');
                JObject current = jsonData;

                // Navigate to the object that will contain the new key
                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else
                    {
                        // If any segment of the path does not exist, create new JObject containers
                        current[keys[i]] = new JObject();
                        current = (JObject)current[keys[i]];
                    }
                }

                // Add the new key with the provided value
                string newKey = keys[keys.Length - 1];
                if (!current.ContainsKey(newKey))
                {
                    current[newKey] = value;  // Directly add the string value
                    this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
                    if (ErrorCode == -1) { return; }

                }
                else
                {
                    ErrorCode = -1;
                    ErrorText = $"Key '{newKey}' 已经存在";
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "添加失败:" + ex.Message;
            }
        }
        public void AddKeyValue(string keyName, float value, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            JObject jsonData = LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                // Split the path to find the parent object
                string[] keys = keyName.Split('.');
                JObject current = jsonData;

                // Navigate to the object that will contain the new key
                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else
                    {
                        // If any segment of the path does not exist, create new JObject containers
                        current[keys[i]] = new JObject();
                        current = (JObject)current[keys[i]];
                    }
                }

                // Add the new key with the provided value
                string newKey = keys[keys.Length - 1];
                if (!current.ContainsKey(newKey))
                {
                    current[newKey] = value;  // Directly add the string value
                    this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
                    if (ErrorCode == -1) { return; }
                }
                else
                {
                    ErrorCode = -1;
                    ErrorText = $"Key '{newKey}' 已经存在";
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "添加失败:" + ex.Message;
            }
        }
        public void AddKeyValue(string keyName, bool value, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            JObject jsonData = LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                // Split the path to find the parent object
                string[] keys = keyName.Split('.');
                JObject current = jsonData;

                // Navigate to the object that will contain the new key
                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else
                    {
                        // If any segment of the path does not exist, create new JObject containers
                        current[keys[i]] = new JObject();
                        current = (JObject)current[keys[i]];
                    }
                }

                // Add the new key with the provided value
                string newKey = keys[keys.Length - 1];
                if (!current.ContainsKey(newKey))
                {
                    current[newKey] = value;  // Directly add the string value
                    this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
                    if (ErrorCode == -1) { return; }

                }
                else
                {
                    ErrorCode = -1;
                    ErrorText = $"Key '{newKey}' 已经存在";
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "添加失败:" + ex.Message;
            }
        }

        /// <summary>
        /// 修改键值
        /// </summary>
        /// <param name="keyName">键</param>
        /// <param name="value">值</param>
        public void ModifyValue(string keyName, JToken value, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            JObject jsonData = this.LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                string[] keys = keyName.Split('.');
                JObject current = jsonData;

                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else if (current[keys[i]] is null || !(current[keys[i]] is JObject))
                    {
                        ErrorCode = -1;
                        ErrorText = keys[i] + "不存在";
                        return;
                    }
                }

                // Use compatible syntax for C# 7.3

                current[keys[keys.Length - 1]] = value;
                this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "修改失败:" + ex.Message;
            }
        }
        public void ModifyValue(string keyName, int value, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            JObject jsonData = this.LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                string[] keys = keyName.Split('.');
                JObject current = jsonData;

                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else if (current[keys[i]] is null || !(current[keys[i]] is JObject))
                    {
                        ErrorCode = -1;
                        ErrorText = keys[i] + "不存在";
                        return;
                    }
                }

                // Use compatible syntax for C# 7.3
                current[keys[keys.Length - 1]] = value;
                this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "修改失败:" + ex.Message;
            }
        }

        public void ModifyValue(string keyName, float value, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            JObject jsonData = this.LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                string[] keys = keyName.Split('.');
                JObject current = jsonData;

                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else if (current[keys[i]] is null || !(current[keys[i]] is JObject))
                    {
                        ErrorCode = -1;
                        ErrorText = keys[i] + "不存在";
                        return;
                    }
                }

                // Use compatible syntax for C# 7.3
                current[keys[keys.Length - 1]] = value;
                this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "修改失败:" + ex.Message;
            }
        }

        public void ModifyValue(string keyName, string value, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            JObject jsonData = this.LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                string[] keys = keyName.Split('.');
                JObject current = jsonData;

                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else if (current[keys[i]] is null || !(current[keys[i]] is JObject))
                    {
                        ErrorCode = -1;
                        ErrorText = keys[i] + "不存在";

                        return;
                    }
                }

                // Use compatible syntax for C# 7.3
                current[keys[keys.Length - 1]] = value;
                this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "修改失败:" + ex.Message;
            }
        }

        public void ModifyValue(string keyName, bool value, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            JObject jsonData = this.LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                string[] keys = keyName.Split('.');
                JObject current = jsonData;

                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else if (current[keys[i]] is null || !(current[keys[i]] is JObject))
                    {
                        ErrorCode = -1;
                        ErrorText = keys[i] + "不存在";

                        return;
                    }
                }

                // Use compatible syntax for C# 7.3
                current[keys[keys.Length - 1]] = value;
                this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "修改失败:" + ex.Message;
            }
        }

        /// <summary>
        /// 修改键名称
        /// </summary>
        /// <param name="oldKeyName"></param>
        /// <param name="newKeyName"></param>
        public void ModifyKeyName(string oldKeyName, string newKeyName, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            JObject jsonData = this.LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                string[] keys = oldKeyName.Split(new char[] { '.' });
                JObject current = jsonData;

                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else if (current[keys[i]] is null || !(current[keys[i]] is JObject))
                    {
                        ErrorCode = -1;
                        ErrorText = keys[i] + "不存在";
                        return;
                    }
                }

                string originalKey = keys[keys.Length - 1];

                if (!current.ContainsKey(originalKey))
                {
                    ErrorCode = -1;
                    ErrorText = originalKey + "不存在";
                    return;
                }
                if (current.ContainsKey(newKeyName))
                {
                    ErrorCode = -1;
                    ErrorText = newKeyName + "已存在";
                    return;
                }

                JToken valueToMove = current[originalKey];
                current.Add(newKeyName, valueToMove);
                current.Remove(originalKey);

                this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "修改失败:" + ex.Message;
            }
        }

        /// <summary>
        /// 复制到同层
        /// </summary>
        /// <param name="keyName"></param>
        /// <param name="newKeyName"></param>
        public void copyKeyAtSameLevelWithNewName(string keyName, string newKeyName, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            JObject jsonData = this.LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                string[] keys = keyName.Split(new char[] { '.' });
                JObject current = jsonData;

                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else if (current[keys[i]] is null || !(current[keys[i]] is JObject))
                    {
                        ErrorCode = -1;
                        ErrorText = keys[i] + "不存在";

                        return;
                    }
                }

                string originalKey = keys[keys.Length - 1];

                // Ensure the original key exists and the new key name does not already exist
                if (!current.ContainsKey(originalKey))
                {
                    ErrorCode = -1;
                    ErrorText = originalKey + "不存在";

                    return;
                }

                if (current.ContainsKey(newKeyName))
                {
                    ErrorCode = -1;
                    ErrorText = newKeyName + "已存在";

                    return;
                }

                // Clone the value of the original key
                JToken originalValue = current[originalKey].DeepClone();

                // Add the cloned value under the new key name
                current.Add(newKeyName, originalValue);
                this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "复制失败:" + ex.Message;
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="KeyName"></param>
        public void Delete(string KeyName, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            JObject jsonData = this.LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }

            try
            {
                string[] keys = KeyName.Split(new char[] { '.' });
                JObject current = jsonData;
                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else if (current[keys[i]] is null || !(current[keys[i]] is JObject))
                    {
                        ErrorCode = -1;
                        ErrorText = keys[i] + "不存在";

                    }
                }

                if (!current.Remove(keys[keys.Length - 1]))
                {
                    ErrorCode = -1;
                    ErrorText = keys[keys.Length - 1] + "不存在或已删除";

                }
                else
                {
                    this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
                }

            }
            catch (KeyNotFoundException ex)
            {
                ErrorCode = -1;
                ErrorText = "删除失败:" + ex.Message;
            }
        }

        public T GetValue<T>(string keyName, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            T t = default;
            JObject jsonData = this.LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return t; }
            try
            {
                string[] keys = keyName.Split('.');
                JObject current = jsonData;

                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else if (current[keys[i]] is null || !(current[keys[i]] is JObject))
                    {
                        ErrorCode = -1;
                        ErrorText = keys[i] + "不存在";
                        return t;
                    }
                }
                // Use compatible syntax for C# 7.3
                JToken value = current[keys[keys.Length - 1]];
                t = value.ToObject<T>();

                return t;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "获取失败:" + ex.Message;
                return t;
            }
        }

        public void AddKeyValueClass(string keyName, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            JObject jsonData = LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
            if (ErrorCode == -1) { return; }
            try
            {
                // Split the path to find the parent object
                string[] keys = keyName.Split('.');
                JObject current = jsonData;

                // Navigate to the object that will contain the new key
                for (int i = 0; i < keys.Length - 1; i++)
                {
                    if (current[keys[i]] is JObject next)
                    {
                        current = next;
                    }
                    else
                    {
                        // If any segment of the path does not exist, create new JObject containers
                        current[keys[i]] = new JObject();
                        current = (JObject)current[keys[i]];
                    }
                }

                // Add the new key with the provided value
                string newKey = keys[keys.Length - 1];
                if (!current.ContainsKey(newKey))
                {
                    current.Add(newKey, new JObject { });  // Directly add the string value
                    this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
                    if (ErrorCode == -1) { return; }
                }
                else
                {
                    ErrorText = $"添加失败:Key '{newKey}' 已经存在";
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "添加失败:" + ex.Message;
            }
        }

        public void AddJobject(string Comments, string keyName, JObject keyValuePairs, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            try
            {
                JObject jsonData = LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
                if (ErrorCode == -1) { return ; }
                var jo = jsonData[Comments] as JObject;

                jo.Add(keyName, keyValuePairs);

                this.SaveJsonToFile(jsonData, this.jsonPath, out ErrorCode, out ErrorText);
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "添加失败:" + ex.Message;
            }

        }

        public string GetComments(string Comments, string keyName, string lang, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "";
            try
            {
                string comments = "";
                JObject jsonData = LoadJsonFromFile(this.jsonPath, out ErrorCode, out ErrorText);
                if (ErrorCode == -1) { return null; }
                JObject jc = jsonData[Comments] as JObject;
                JObject jl = jc[keyName] as JObject;
                if (jl != null)
                {
                    comments = jl[lang].ToString();
                }
                return comments;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "获取失败:" + ex.Message;
                return null;
            }

        }

    }
    public enum JValueType
    {
        Integer,
        Float,
        String,
        Boolean
    }
}
